<?php
/*------------------------------------------------------------------------------
this file is part of Web Application Kit http://webappkit.net
Copyright (C) 2006 J.Ducastel <fredbird@fredbird.org>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
------------------------------------------------------------------------------*/

/**
* wak core service : http requests handler, serves them
* retrieves request triggers, and runs events from steps 7 to 1
* step 1 : core reserved events
* step 2 : security events
* step 3 : app routing, controller phase
* step 4 : app actions, model phase
* step 5 : content preparation, view phase
* step 6 : output production
* step 7 : post-output events
* @author J.Ducastel <fredbird@fredbird.org>
* @version 
*/
class wakRequestHandler extends wakService {
/*------------------------------------------------------------------------------
                                                                     constructor
------------------------------------------------------------------------------*/
	/**
	*
	* @access
	* /
	function wakRequestHandler() {
		$this->__construct();
	}/**/
	
	/**
	*
	* @access
	* /
	function __construct() {
		parent::__construct();
	}/**/
/*------------------------------------------------------------------------------
                                                                  public methods
------------------------------------------------------------------------------*/
	/**
	* serve an http request
	* @param wakHttpRequest $request
	* @access public
	* @return bool
	*/
	function serveRequest($req=null) {
		//echo t;
		// getting current request instance if required
		if (!$req) {
			//$io=&$w->getservice('wakio');
			//$req=$io->currentRequest();
			//$lib=wak::getService('waklib');
			//$lib->needClass('httprequestbean',true);
			wakapi::NeedClass('httprequestbean',true);
			$req=httprequestbean::getcurrent();
		}
		$this->request=&$req;
		// setting constants
		$this->_setRequestConstants($req);
		$deb=&wak::getservice('wakdebug');
		// using triggers piles cache ?
		if ($this->cfg['use_triggers_piles_cache']) {
			// getting pile from cache
			$pileCache=&wak::getservice('waktriggerspilescache');
			if ($pile=$pileCache->getPileForRequest($req)) {
				//echo wakapi::vardump($pile);
				$this->pile=&$pile;
			} else {
				// retrieving triggers and building pile
				$TS=&wak::getservice('waktriggerstorage');
				$this->pile=&$TS->buildRequestTriggersPile($req);
				// storing pile into cache
				//$pile=&wak::getservice('waktriggerspile');
				
				$pileCache->storePileForRequest($this->pile,$req);
			}
		} else {
			// retrieving triggers and building pile
			$TS=&wak::getservice('waktriggerstorage');
			$this->pile=&$TS->buildRequestTriggersPile($req);
		}
		
		// executing request steps
		for ($step=1; $step<=7; $step++) {
			$this->toRequestStep($step);
		}
		return true;
	}/**/
	
	/**
	* return current request step
	* @param
	* @access public
	* @return int
	*/
	function currentStep() {
		return $this->current_step;
	}/**/
	
	/**
	* go to a request step, executes it and then 
	* @param
	* @access public
	* @return bool
	*/
	function toRequestStep($step) {
		if (!in_array($step,array(1,2,3,4,5,6,7)))
			return false;
		$this->current_step=$step;
		// benchmarking
		// for benchamrking if relevant
		if ($this->cfg['use_benchmark_logs']) {
			$BM=&wak::getservice('wakbenchmark');
			$BM->timeFlag('steps','step'.$step);
		}
		// before triggers actions
		$method='_beforeStep_'.$step;
		if (method_exists($this,$method))
			$this->$method();
		// running step triggers
		$this->_runStepTriggers($step);
		// after triggers actions
		$method='_afterStep_'.$step;
		if (method_exists($this,$method))
			$this->$method();
		// going next step
		//if ($step<7)	return $this->toRequestStep($step+1);
		return true;
	}/**/
	
	/**
	* clear (removes) all triggers at step
	* @param
	* @access public
	* @return bool
	*/
	function clearTriggers($step=null) {
		//$pile=&wak::getservice('waktriggerspile');
		return $this->pile->clear($step);
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	* /
	function () {
		
	}/**/
	
	/**
	* 
	* @param
	* @access public
	* @return 
	* /
	function () {
		
	}/**/
/*------------------------------------------------------------------------------
                                                                      properties
------------------------------------------------------------------------------*/
	/**
	*
	*/
	var $cfg=array(
		'use_triggers_piles_cache'=>false
		, 'use_benchmark_logs'=>false
	);
	
	/**
	* @var type desc
	*/
	//var //
	var $current_step=0;
	/**
	* @var httprequestbean current request
	*/
	var $request;
	/**
	* @var waktriggerspile
	*/
	var $pile;
/*------------------------------------------------------------------------------
                                                                 private methods
------------------------------------------------------------------------------*/
	/**
	* executes a request step
	* 
	* /
	function _requestStep($step) {
		
	}/**/
	
	

	/**
	* run request step triggers
	* @access private
	* @param int runlevel
	* @return int triggers ran
	*/
	function _runStepTriggers($step) {
		// echo "<p>step $step</p>";
		//$pile=&wak::getservice('waktriggerspile');
		// for benchamrking if relevant
		if ($this->cfg['use_benchmark_logs']) {
			$BM=&wak::getservice('wakbenchmark');
			$request_id=$this->request->makeid();
		}
		$n=0;
		if (!is_int($step) or $step>7 or $step<0)
			return $n;
		//echo wakdebug::vardump($pile->dumpastext(),'html',500);
		while ($trigger=$this->pile->shift($step)) {
			if ($n>50) break; // infinite loop protection
			// $this->_runtrigger($trigger); $n++;
			//echo "<p>running trigger ".$trigger->get('comments').', event '.$trigger->getevent()."</p>";
			if ($trigger->run()) $n++;
			// for benchamrking if relevant
			if ($this->cfg['use_benchmark_logs']) {
				$flag=$this->current_step
				.'.'.$trigger->get('priority')
				.'.'.$trigger->get('event_call');
				$BM->timeflag($request_id,$flag);
			}
		}
		//echo "<p>ran $n triggers at step $step</p>";
		return $n;
	}/**/
	
	/**
	* actions before step 6
	* @param
	* @access private
	* @return bool
	* /
	function _beforeStep_1() {
		// storing built triggers pile for request
		$pileCache=&wak::getservice('waktriggerspilescache');
		$pileCache->storePileForRequest();
		return true;
	}/**/

	/**
	* actions before step 6
	* @param
	* @access private
	* @return bool
	*/
	function _beforeStep_6() {
		// send http response headers
		$builder=&wak::getservice('wakresponsebuilder');
		$builder->sendHeaders();
		return true;
	}/**/

	/**
	* actions after step 6
	* @param
	* @access private
	* @return bool
	*/
	function _afterStep_6() {
		// send stored http content
		$builder=&wak::getservice('wakresponsebuilder');
		$builder->sendContent();
		return true;
	}/**/
	
	function _afterstep_7() {
		// for benchamrking if relevant
		if ($this->cfg['use_benchmark_logs']) {
			$BM=&wak::getservice('wakbenchmark');
			$BM->timeFlag('steps','ended');
			$BM->saveLogs();
		}
		//$BM->__destruct();
	}
	
	/**
	* sets request constants
	* @param httpRequestBean &$req
	* @access private
	* @return bool
	*/
	function _setRequestConstants(&$req) {
		//echo wakdebug::vardump($req);
		if (!defined('METHOD'))
			define('METHOD',$req->getMethod());
		if (!defined('CLIENT_IP'))
			define('CLIENT_IP',$req->getClientIp());
		if (!defined('URI'))
			define('URI',$req->getUri());
		if (!defined('BASE_HREF'))
			define('BASE_HREF',$req->getBaseHref());
		if (!defined('BASE_PATH'))
			define('BASE_PATH',$req->getBasePath());
		//echo BASE_HREF;
		return true;
	}/**/
	
	/**
	* 
	* @param
	* @access private
	* @return 
	* /
	function () {
		
	}/**/
}
?>
